<?php
/**
 * 策略模式: 定义一组算法类，将每个算法分别封装起来，让它们可以互相替换
 * 下面代码演示使用策略模式实现一个加减乘除的计算器
 */

/**
 * 定义一个接口,包含一个"计算"的方法
 */
interface Math {
    public function calc($num1, $num2);
}

class Add implements Math {
    public function calc($num1, $num2) {
        return $num1 + $num2;
    }
}

class Subtract implements Math {
    public function calc($num1, $num2) {
        return $num1 - $num2;
    }
}

class Multiply implements Math {
    public function calc($num1, $num2) {
        return $num1 * $num2;
    }
}

class Divide implements Math {
    public function calc($num1, $num2) {
        return $num1 / $num2;
    }
}

/**
 * 封装一个计算器类
 */
class MyMath {
    private $strategy;

    public function __construct(Math $operate) {
        $this->strategy = $operate;
    }

    public function myCalc($num1, $num2) {
        return $this->strategy->calc($num1, $num2);
    }
}

//客户端调用
$number1 = 8;
$number2 = 5;
$add = new MyMath(new Add());
echo $add->myCalc($number1, $number2) . PHP_EOL; //13

$subtract = new MyMath(new Subtract());
echo $subtract->myCalc($number1, $number2) . PHP_EOL; //3

$multiply = new MyMath(new Multiply());
echo $multiply->myCalc($number1, $number2) . PHP_EOL; //40

$divide = new MyMath(new Divide());
echo $divide->myCalc($number1, $number2) . PHP_EOL; //1.6
